import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

/// Dio 网络请求工具类
///
/// 提供预配置的 Dio 单例实例，支持不同超时配置
///
/// 使用示例：
/// ```dart
/// // 方式1：直接获取数据（推荐，最简洁）
/// final data = await DioUtil.getData<Map<String, dynamic>>('https://api.example.com/data');
/// final result = await DioUtil.postData<Map<String, dynamic>>('https://api.example.com/submit', data: {'key': 'value'});
///
/// // 方式2：获取完整 Response 对象（需要访问 statusCode、headers 等信息时使用）
/// final response = await DioUtil.get<Map<String, dynamic>>('https://api.example.com/data');
/// print(response.statusCode);
/// print(response.data);
///
/// // 方式3：使用长超时实例（2分钟），适用于上传/下载大文件
/// final uploadResponse = await DioUtil.longTimeout.post('https://api.example.com/upload');
///
/// // 方式4：使用短超时实例（5秒），适用于快速响应的接口
/// final quickResponse = await DioUtil.shortTimeout.get('https://api.example.com/ping');
/// ```
class DioUtil {
  DioUtil._();

  static final Map<String, Dio> _instances = {};

  /// 默认 Dio 实例（私有）
  ///
  /// 超时配置：连接/接收/发送均为 30 秒
  /// 已启用日志拦截器
  static Dio get _default => _getInstance();

  /// 长超时 Dio 实例
  ///
  /// 超时配置：连接/接收均为 2 分钟
  /// 适用场景：上传/下载大文件、耗时较长的接口
  static Dio get longTimeout => _getInstance(
        key: 'long',
        connectTimeout: const Duration(minutes: 2),
        receiveTimeout: const Duration(minutes: 2),
      );

  /// 短超时 Dio 实例
  ///
  /// 超时配置：连接/接收均为 5 秒
  /// 适用场景：健康检查、快速响应的接口
  static Dio get shortTimeout => _getInstance(
        key: 'short',
        connectTimeout: const Duration(seconds: 5),
        receiveTimeout: const Duration(seconds: 5),
      );

  /// GET 请求（使用默认实例）
  ///
  /// 示例：
  /// ```dart
  /// final response = await DioUtil.get('https://api.example.com/data');
  /// ```
  static Future<Response<T>> get<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onReceiveProgress,
  }) {
    return _default.get<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onReceiveProgress: onReceiveProgress,
    );
  }

  /// POST 请求（使用默认实例）
  ///
  /// 示例：
  /// ```dart
  /// final response = await DioUtil.post('https://api.example.com/submit', data: {'key': 'value'});
  /// ```
  static Future<Response<T>> post<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) {
    return _default.post<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onSendProgress: onSendProgress,
      onReceiveProgress: onReceiveProgress,
    );
  }

  /// GET 请求并直接返回数据（使用默认实例）
  ///
  /// 返回 response.data，而不是完整的 Response 对象
  ///
  /// 示例：
  /// ```dart
  /// final data = await DioUtil.getData<Map<String, dynamic>>('https://api.example.com/data');
  /// ```
  static Future<T> getData<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onReceiveProgress,
  }) async {
    final response = await _default.get<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onReceiveProgress: onReceiveProgress,
    );
    return response.data as T;
  }

  /// POST 请求并直接返回数据（使用默认实例）
  ///
  /// 返回 response.data，而不是完整的 Response 对象
  ///
  /// 示例：
  /// ```dart
  /// final data = await DioUtil.postData<Map<String, dynamic>>('https://api.example.com/submit', data: {'key': 'value'});
  /// ```
  static Future<T> postData<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    final response = await _default.post<T>(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onSendProgress: onSendProgress,
      onReceiveProgress: onReceiveProgress,
    );
    return response.data as T;
  }

  /// 获取指定配置的 Dio 实例（私有方法）
  ///
  /// 每个 key 对应一个单例，相同 key 返回同一实例
  static Dio _getInstance({
    String key = 'default',
    Duration? connectTimeout,
    Duration? receiveTimeout,
    Duration? sendTimeout,
    bool enableLog = true,
  }) {
    if (_instances.containsKey(key)) {
      return _instances[key]!;
    }

    final dio = Dio(BaseOptions(
      connectTimeout: connectTimeout ?? const Duration(seconds: 30),
      receiveTimeout: receiveTimeout ?? const Duration(seconds: 30),
      sendTimeout: sendTimeout ?? const Duration(seconds: 30),
    ));

    if (enableLog) {
      dio.interceptors.add(LogInterceptor(
        request: true, // 打印请求基本信息
        requestHeader: true, // 打印请求头
        requestBody: true, // 打印请求体
        responseHeader: true, // 打印响应头
        responseBody: true, // 打印响应体
        error: true, // 打印错误信息
        logPrint: (object) => debugPrint(object.toString()),
      ));
    }

    _instances[key] = dio;
    return dio;
  }
}